package demo4;

public class MySingleList implements IList {
    static class ListNode{
        public int val;
        public ListNode next;

        public ListNode(int val) {
            this.val = val;
        }
    }
    public ListNode head;
    @Override
    public void display() {
        ListNode cur=head;
        while (cur!=null){
            System.out.print(cur.val+" ");
            cur=cur.next;
        }
    }

    @Override
    public void createList() {
        ListNode node1=new ListNode(12);
        ListNode node2=new ListNode(23);
        ListNode node3=new ListNode(34);
        ListNode node4=new ListNode(45);
        ListNode node5=new ListNode(56);

        node1.next=node2;
        node2.next=node3;
        node3.next=node4;
        node4.next=node5;
        head=node1;

    }

    @Override
    public int size() {
        int len=0;
        ListNode cur=head;
        while (cur!=null){
            len++;
            cur=cur.next;
        }
        return len;
    }

    @Override
    public boolean contains(int key) {
        /*if(head==null){
            return false;
        }*/
        //不用额外在考虑head为空的情况了，因为在循环条件的判断时，
        // 已经考虑到链表为空，即head==null的情况了。
        ListNode cur=head;
        while (cur!=null){
            if(cur.val==key){
                return true;
            }
            cur=cur.next;
        }
        return false;
    }

    @Override
    public void addFirst(int data) {
        ListNode node=new ListNode(data);
        node.next=head;
        head=node;
    }

    @Override
    public void addLast(int data) {
        ListNode node=new ListNode(data);
        //考虑链表 为空情况
        if(head==null){
            head=node;
            return;
        }
        ListNode cur=head;
        while (cur.next!=null){
            cur=cur.next;
        }
        cur.next=node;
        //因为上面这行代码已经能够，表示出node的位置，不需要在写下面 这行代码了，画蛇添足了。
        //node.next=null

    }

    @Override
    public void addInsert(int pos, int data) {
        int len=size();
        /*if(pos<0||pos>len){
            System.out.println("pos位置不合法");
            return;
        }*/
        //用自定义异常
        if(pos<0||pos>len){
            throw new PosIllegal("pos 位置不合法");
        }
        //头插
        if(pos==0){
            addFirst(data);
            return;
        }
        //尾插
        if(pos==len){
            addLast(data);
            return;
        }
        //中间插pos范围在1~len-1
        ListNode node=new ListNode(data);
        ListNode cur=head;
        while (pos-1!=0){
            cur=cur.next;
            pos--;
        }
        node.next=cur.next;
        cur.next=node;
    }

    @Override
    public void remove(int key) {
        if(head==null){
            return;
        }
        if(head.val==key){
            head=head.next;
            return;
        }
        //找到被删除节点的前一个
        ListNode cur=findCurPrev(key);
        if(cur==null){
            return;
        }
        //ListNode del=new ListNode(key);
        ListNode del=cur.next;//未知数放在左边
        cur.next=del.next;

    }
    private ListNode findCurPrev(int key){
        ListNode cur=head;
        while (cur.next!=null)//cur.next!=null表示最后一个结点遍历不到
        {
            if(cur.next.val==key){
                return cur;
            }
            cur=cur.next;
        }
        return null;
    }

    @Override
    public void removeAllKey(int key) {
        if(head==null){
            return;
        }
        //没考虑头结点是否是要被删除的结点
        ListNode prev=head;
        ListNode cur=head.next;
        while (cur!=null){
            if(cur.val==key){
                prev.next=cur.next;
                cur=cur.next;
            }else {
                prev=cur;
                cur=cur.next;
            }
        }
        //考虑头结点是否是要被删除的结点
        if(head.val==key){
            head=head.next;
        }
    }

    @Override
    public void clear() {
        ListNode cur=head;
        while (cur!=null){
          ListNode curN=cur.next;
          cur.next=null;
          cur=curN;
        }
        head=null;
    }
}
